﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using System.Reflection;
using System.IO.Pipes;
using System.Media;
using System.Runtime.InteropServices;
using System.Reflection;
using System.IO;

namespace WindowsFormsApplication1
{
    /// <summary>
    /// 设置块的枚举，要从1开始，加入地图时直接转成int类型放入地图就可以了。
    /// </summary>
    //enum ShapeType { O = 1, S, T, J, Z, L, I };
    enum ShapeType { O = 1, S, T, J, Z, L, I, OB, PROMPT };
    public partial class Form1 : Form
    {
        protected override bool ProcessDialogKey(Keys keyData)
        {
            if (keyData == Keys.Up ||
                keyData == Keys.Down ||
                keyData == Keys.Left ||
                keyData == Keys.Right)
                return false;

            return base.ProcessDialogKey(keyData);
        }


        int[,] gameMap = new int[12, 25];
        Shape s;
        Shape Next;
        Shape Lock;
        Shape Ram;//缓存形状
        Boolean lockBoolean;
        Graphics mainGraphics;
        Graphics subGraphics;
        Graphics lockGraphics;
        Boolean pause;
        Boolean canSwitch;//可以使用l键转换
        int interval = 500;//游戏速度
        int intervalSaver = 500;//保存速度设置

        int interval_grade = 500; //等级速度设置


        int interval_Reduce = 0;//减速功能的修正值
        int interval_Reduce_Depend = 500;

        //控制是否开启穿墙块
        Boolean ifSpecialBlock = false;

        //清除一行事件是否发生
        Boolean ifCleanALine = false;

        private int previousSelectedIndex;

        String result = "";
        static string userInput;
        static string selectedOption; // 保存用户选择的下拉框内容
        static int money; // 保存用户充值的钱
        static int user_balance; // 保存当前用户的钱
        static Boolean isNumeric; // 是否充值成功
        int money1 = 100;
        int moneyPrompt = 10;
        Boolean enableCalculate = false;
        Shape promptShape = null;

        static int user_total = 11;
        static int save_user = 10;
        //设置按钮禁用
        Boolean button_boolean = false;

        PersorScore[] persorscore = GetPersor("save.txt");

        string path= "save.txt";

        int orderint = 10;



        // 输入界面窗体类
        class InputForm : Form
        {
            TextBox textBox;
           // ComboBox comboBox;
            Button button;

            public InputForm()
            {
                // 设置窗体属性
                Text = "请输入用户名";
                Width = 300;
                Height = 200;

                // 创建文本框
                textBox = new TextBox();
                textBox.Left = 20;
                textBox.Top = 50;
                textBox.Width = 200;
/*                // 创建下拉框
                comboBox = new ComboBox();
                comboBox.Left = 20;
                comboBox.Top = 60;
                comboBox.Width = 200;
                comboBox.Items.AddRange(new string[] { "难度一", "难度二", "难度三", "难度四", "难度五" });*/

                // 创建按钮
                button = new Button();
                button.Left = 20;
                button.Top = 100;
                button.Width = 100;
                button.Text = "登陆";
                button.Click += Button_Click;

                // 将控件添加到窗体
                Controls.Add(textBox);
               // Controls.Add(comboBox);
                Controls.Add(button);



            }

            // 按钮点击事件处理程序
            private void Button_Click(object sender, EventArgs e)
            {
                // 获取文本框的输入内容
                userInput = textBox.Text;

                if (string.IsNullOrWhiteSpace(userInput))
                {
                    MessageBox.Show("请重新启动程序，并输入正确的用户", "登录失败");
                    Environment.Exit(0);
                }
                // 获取下拉框的选中内容
                //selectedOption = comboBox.SelectedItem.ToString();
                // 关闭输入界面窗体
                Close();
            }
        }


        // 输入界面窗体类
        class InputForm1 : Form
        {
            ComboBox comboBox;
            Button button;

            public InputForm1()
            {
                // 设置窗体属性
                Text = "请选择难度等级";
                Width = 300;
                Height = 200;

       
                // 创建下拉框
                comboBox = new ComboBox();
                comboBox.Left = 20;
                comboBox.Top = 30;
                comboBox.Width = 200;
                comboBox.Items.AddRange(new string[] { "难度一", "难度二", "难度三", "难度四", "难度五" });

                // 创建按钮
                button = new Button();
                button.Left = 20;
                button.Top = 100;
                button.Width = 100;
                button.Text = "确定";
                button.Click += Button_Click;

                // 将控件添加到窗体
                Controls.Add(comboBox);
                Controls.Add(button);
            }

            // 按钮点击事件处理程序
            private void Button_Click(object sender, EventArgs e)
            {
                // 获取下拉框的选中内容
                selectedOption = comboBox.SelectedItem.ToString();
                // 关闭输入界面窗体
                Close();
            }
        }

        class InputForm2 : Form
        {
            TextBox textBox;
            // ComboBox comboBox;
            Button button;

            public InputForm2()
            {
                // 设置窗体属性
                Text = "请支付金额";
                Width = 300;
                Height = 200;

                // 创建文本框
                textBox = new TextBox();
                textBox.Left = 20;
                textBox.Top = 50;
                textBox.Width = 200;
                /*                // 创建下拉框
                                comboBox = new ComboBox();
                                comboBox.Left = 20;
                                comboBox.Top = 60;
                                comboBox.Width = 200;
                                comboBox.Items.AddRange(new string[] { "难度一", "难度二", "难度三", "难度四", "难度五" });*/

                // 创建按钮
                button = new Button();
                button.Left = 20;
                button.Top = 100;
                button.Width = 100;
                button.Text = "支付";
                button.Click += Button_Click;

                // 将控件添加到窗体
                Controls.Add(textBox);
                // Controls.Add(comboBox);
                Controls.Add(button);
            }

            // 按钮点击事件处理程序
            private void Button_Click(object sender, EventArgs e)
            {


                isNumeric = int.TryParse(textBox.Text, out money);
                if (!isNumeric)
                {
                    MessageBox.Show("请输入正确的金额", " 充值失败");
                }
                
                Close();
            }
        }

        public Form1()
        {
            InitializeComponent();
            this.DoubleBuffered = true;
            //this.BackColor = ColorTranslator.FromHtml("#FFFFFF");
            SoundPlayer sp = new SoundPlayer(WindowsFormsApplication1.Properties.Resources.bgm1);
            sp.PlayLooping(); //开启
        }

/*        private void my_combox()
        {
            comboBox1.Items.Add("难度一");
            comboBox1.Items.Add("难度二");
            comboBox1.Items.Add("难度三");
            comboBox1.Items.Add("难度四");
            comboBox1.Items.Add("难度五");
        }
*/
        private void Form1_Load(object sender, EventArgs e)

        {
            InputForm inputForm = new InputForm();

            // 显示输入界面窗体并等待用户输入
            inputForm.ShowDialog();
            persorscore[user_total-1].Name = userInput;


            label12.Text = persorscore[0].score.ToString();

            // listView1.OwnerDraw = true;
            //listView1.DrawColumnHeader += listView1_DrawColumnHeader;
            // listView1.DrawSubItem += listView1_DrawSubItem;

            for (int i = 0; i < save_user; i++)
            {
                if (persorscore[i].Name == userInput)
                {
                    user_balance = persorscore[i].money;
                }
            }
            persorscore[user_total - 1].money = user_balance;
            label8.Text=user_balance.ToString();

            if (int.Parse(label8.Text) >= money1)
            {
                技能一ToolStripMenuItem.Enabled = true;
            }
            else
            {
                技能一ToolStripMenuItem.Enabled = false;
            }

            if (int.Parse(label8.Text) >= money1)
            {
                技能二ToolStripMenuItem.Enabled = true;
            }
            else
            {
                技能二ToolStripMenuItem.Enabled = false;
            }

            if (int.Parse(label8.Text) >= money1)
            {
                启动提示ToolStripMenuItem.Enabled = true;
            }
            else
            {
                启动提示ToolStripMenuItem.Enabled = false;
            }

            if (int.Parse(label8.Text) >= money1)
            {
                清除一行ToolStripMenuItem.Enabled = true;
            }
            else
            {
                清除一行ToolStripMenuItem.Enabled = false;
            }
            // 绑定数据源到 DataGridView
            // dataGridView1.DataSource = yourDataSource; // 设置为你的数据源对象

            // my_combox();
            canSwitch = true;
            mainGraphics = panel1.CreateGraphics();
            subGraphics = panel2.CreateGraphics();
            lockGraphics = panel3.CreateGraphics();
            lockBoolean = false;//锁定变量 false代表没有锁定形状
            s = randomShape();
           // s.backgroundImage = this.BackgroundImage;
            do
            {
                Next = randomShape();

             //   Next.backgroundImage = this.BackgroundImage;
            } while (s.shape == Next.shape);//生成一个与s不同的块，采用伪随机
            Next.shapeDrawSub(subGraphics);
            timer1.Interval = 500;
            timer2.Interval = 500;
            timer3.Interval = 5000;
            timer1.Start();
            timer2.Start();
            timer3.Start();

            FunctionCollection.BackgroundImage = this.BackgroundImage;

        }


        private void set_difficulty()
        {
            if (selectedOption == "难度一")
            {

                interval =  interval_grade ;
                intervalSaver = interval;
            }
            else if (selectedOption == "难度二")
            {
                
                interval = 4 * interval_grade / 5;
                intervalSaver = interval;
            }
            else if (selectedOption == "难度三")
            {
                interval = 3 * interval_grade / 5;
                intervalSaver = interval;
            }
            else if (selectedOption == "难度四")
            {
                interval = 2 * interval_grade / 5;
                intervalSaver = interval;
            }
            else if (selectedOption == "难度五")
            {
                interval = interval_grade / 5;
                intervalSaver = interval;
            }
        }
        private void timer1_Tick(object sender, EventArgs e)
        {
/*            mainGraphics.Clear(Control.DefaultBackColor);
            FunctionCollection.mapDraw(gameMap, mainGraphics);
            if (promptShape != null)
                promptShape.shapeDrawMain(mainGraphics);
            s.shapeDrawMain(mainGraphics);*/
            //mainGraphics.Clear(Color.Transparent);
            FunctionCollection.mapDraw(gameMap, mainGraphics,promptShape,s);


            /**************************清除一行功能：如果点击了清除一行，那么在tick事件时，将最后一行填满并调用getScore函数清理最后一行******************************/


            if (ifCleanALine)
            {
                for (int i = 0; i < 12; i++)
                {
                    gameMap[i, 24] = 1;

                }
                //清除一行
                FunctionCollection.getScore(gameMap);

                ifCleanALine = false;

            }


            /**************************清除一行功能：如果点击了清除一行，那么在tick事件时，将最后一行填满并调用getScore函数清理最后一行*******************************/


            /************************************减速功能：点击减速，则这个速度会加上一个修正值,**********************************************/

            if (interval_Reduce_Depend != interval)
            {
                interval += interval_Reduce;
                interval_Reduce_Depend = interval;
            }

            /************************************减速功能：点击减速，则这个速度会加上一个修正值**********************************************/

        }
        private void timer2_Tick(object sender, EventArgs e)
        {

            gameMain();
        }

        private void timer3_Tick(object sender, EventArgs e)
        {

            RefreshListView();
        }
        /// <summary>
        /// 游戏主逻辑
        /// </summary>
        private void gameMain()
        {
            Next.shapeDrawSub(subGraphics);
            
            //这个方法写入timer2作为逻辑方法
            if (!s.moveDown(gameMap))//移动成功了就下落不然就添加至地图，进入if内
            {
                FunctionCollection.gameOver(gameMap, timer2, result, path);
                s = Next;
                do
                {
                    Next = randomShape();
                   // Next.backgroundImage = this.BackgroundImage; 
                } while (s.shape == Next.shape);//生成一个与s不同的块，采用伪随机

                subGraphics.Clear(ColorTranslator.FromHtml("#C7D9E3"));
                Next.shapeDrawSub(subGraphics);
                canSwitch = true;//解锁L键
                label4.Text = (FunctionCollection.getScore(gameMap) + int.Parse(label4.Text)).ToString("000000");

                //根据分数提速,每累计2000分提高50，最低速度50
                //int score = int.Parse(label4.Text);
                //if (score / 2000 > 0 && interval > 50)
                //{
                //    //interval = (300 - 50 * (score / 2000));
                //}

                /**********************提速修改：每累计1500分，这个档次中速度就增25，但是总速度不低于50*********************************/
                int score = int.Parse(label4.Text);
                if (score / 1500 > 0 && interval > 50)
                {
                    interval = (intervalSaver - 20 * (score / 1500));
                    label6.Text = "第"+ ((score/1500)+1).ToString() +"关";
                }

                /***************************提速修改：每累计2000分，这个档次中速度增20，但是总速度不低于50**************************/

                promptShape = null;
                timer2.Interval = interval;//因为按下Down键会快速下落所以每次加入地图后需要重置timer2的interval
            }
            else
            {
                // AI智能玩配合落地音效太吵了, 如果放开, 建议把落地音效关了
                //CalculatePos.calculate(gameMap, s, mainGraphics);
                int m = int.Parse(label8.Text);
                启动提示ToolStripMenuItem.Enabled = m >= moneyPrompt;
                if (m < moneyPrompt)
                {
                    promptShape = null;
                    enableCalculate = false;
                    启动提示ToolStripMenuItem.Text = "启用提示";
                }
                if (enableCalculate && promptShape == null && m >= moneyPrompt && s._shape != ShapeType.OB)
                {
                    promptShape = CalculatePos.calculate(gameMap, s, mainGraphics);
                    m -= moneyPrompt;
                    label8.Text = m.ToString("000000");
                    
                }
                if(!enableCalculate && promptShape != null)
                {
                    promptShape = null;
                }
            };
        }
        /// <summary>
        /// 获取一个随机块
        /// </summary>
        /// <returns></returns>
        private Shape randomShape()
        {
            Random r = new Random();
            int choose;
            if (ifSpecialBlock)
            {
                choose = 8;
            }
            else
            {
                choose = r.Next(0, 8);
            }


            //switch (r.Next(0, 9))
            switch(choose)
            {
                case (1): return new shapeO();
                case (2): return new shapeOther(ShapeType.J);
                case (3): return new shapeOther(ShapeType.L);
                case (4): return new shapeOther(ShapeType.S);
                case (5): return new shapeOther(ShapeType.T);
                case (6): return new shapeOther(ShapeType.Z);
                //穿墙块
                case (8):
                    {
                        if (ifSpecialBlock)
                        {
                            ifSpecialBlock = false;
                            return new shapeOneBlock();
                            //return new shapeOther(ShapeType.OB);
                            

                        }
                        else
                        {
                            switch (r.Next(0, 8))
                            {
                                case (1): return new shapeO();
                                case (2): return new shapeOther(ShapeType.J);
                                case (3): return new shapeOther(ShapeType.L);
                                case (4): return new shapeOther(ShapeType.S);
                                case (5): return new shapeOther(ShapeType.T);
                                case (6): return new shapeOther(ShapeType.Z);
                                default: return new shapeI();
                            }
                        }

                    }
                default: return new shapeI();
            }


        }



        // 刷新排行榜
        private void RefreshListView()
        {
            // 每次刷新时更新ListView内容

            int score_single = int.Parse(label4.Text);
            listView1.BackColor = ColorTranslator.FromHtml("#FFFFFF");

            // 清除ListView中的所有项
            listView1.Items.Clear();
            // listView1.OwnerDraw = true;
            // listView1.DrawItem += ListView_DrawItem;

            /*          for (int i = 0; i < num; i++)
                      {

                      }*/
            int rowHeight = 30;
            imageList1.ImageSize = new Size(20, rowHeight);
            listView1.LargeImageList = imageList1;



            persorscore[orderint].score = score_single;
            persorscore[orderint].money = int.Parse(label8.Text);

            for(int i = 0; i < save_user; i++)
            {
                if (persorscore[i].Name == userInput)
                {
                    persorscore[i].money = int.Parse(label8.Text);
                }
            }

            for(int j = orderint; j> 0; j--)
            {
                if (persorscore[j].score > persorscore[j - 1].score)
                {
                    PersorScore per = new PersorScore();
                    per.score = persorscore[j].score; ;
                    per.Name = persorscore[j].Name;
                    per.money = persorscore[j].money;
                    per.head_portrait = persorscore[j].head_portrait;

                    persorscore[j] = persorscore[j-1];
                    persorscore[j - 1] = per;
                }
                else
                {
                    orderint = j;
                    break;
                }
            }

            label10.Text = (orderint + 1).ToString();
            label12.Text = persorscore[0].score.ToString();


            /*            if (orderint > 0 && score_single > persorscore[orderint - 1].score)
                        {
                            PersorScore per = new PersorScore();
                            per.score = score_single;
                            per.Name = persorscore[orderint].Name;
                            per.head_portrait = persorscore[orderint].head_portrait;

                            persorscore[orderint] = persorscore[orderint - 1];
                            persorscore[orderint - 1] = per;
                            orderint--;
                        }*/

            /*            for (int i = 0; i < 10; i++)
                        {
                            if (persorscore[i].Name == "zhao")
                                persorscore[i].score = score_single;
                        }
                        Array.Sort(persorscore, (x, y) => y.score.CompareTo(x.score));*/
            // persorscore = persorscore.OrderBy(p => p.score).ToArray();


            //ListViewItem[] items = new ListViewItem[10];
            result = "";
            for (int i = 0; i < save_user; i++)
            {

                result += persorscore[i].Name + "," + persorscore[i].score+","+persorscore[i].money + "\n";
                //string file_name = (i + 2).ToString();
                imageList1.Images.Add(Image.FromFile(persorscore[i].head_portrait));
                ListViewItem item = new ListViewItem();
                item.ImageIndex = i;


                item.SubItems.Add((i + 1).ToString());
                item.SubItems.Add(persorscore[i].Name);
                item.SubItems.Add(persorscore[i].score.ToString());

                // 判断行号的奇偶性
                if (i % 2 == 0)
                {
                    // 偶数行，设置背景颜色为灰色
                    item.BackColor = Color.LightGray;
                }
                else
                {
                    // 奇数行，设置背景颜色为白色
                    item.BackColor = Color.White;
                }

                listView1.Items.Add(item);
            }


            /*            for(int i = 0; i < 10;i++)
                        {
                            listView1.Items.Add(items[i]);
                        }*/



            // 加载图片到ImageList
            // imageList1.Images.Add("image1", Image.FromFile("D:\\workspace\\workspace_C_sharp\\file\\2.png"));

            //imageList1.Images.Add("image2", Image.FromFile("path_to_image2.jpg"));
            // 可以根据需要添加更多图片

            // 创建ListViewItem，并为每个项指定相应的图像索引
            /*            ListViewItem item1 = new ListViewItem();
                        item1.ImageIndex = 0;
                        item1.SubItems.Add("ni");
                        item1.SubItems.Add("10");
                        item1.SubItems.Add("100");

                        ListViewItem item2 = new ListViewItem();
                        item2.ImageIndex = 1;
                        item2.SubItems.Add("nihao");
                        item2.SubItems.Add("2");
                        item2.SubItems.Add("100");
                        //ListViewItem item2 = new ListViewItem("行2文本", "image2");
                        // 可以根据需要创建更多项

                        // 将ListViewItem添加到ListView中
                        listView1.Items.Add(item1);
                        listView1.Items.Add(item2);*/
            // listView1.Items.Add(item2);
            // 创建新的ListViewItem并添加到ListView中

        }



        private static PersorScore[] GetPersor(string path )
        {
            PersorScore[] persorScores = new PersorScore[user_total];
            // int[] score = new int[10] { 0, 1500, 3500, 5600, 8000, 8600, 9900, 12000, 15000, 18000 };
            int[] score = new int[user_total] ;
            int[] money_all = new int[user_total] ;
            string[] name = new string[] {" "," "," "," "," ", " "," "," "," "," ",""};
            if (File.Exists(path))
            {
                StreamReader reader = File.OpenText(path);
            
                string line;
                int count = 0;

                    while ((line = reader.ReadLine()) != null)
                    {
                        string[] fields = line.Split(',');
                        score[count] = int.Parse(fields[1]);
                        money_all[count] = int.Parse(fields[2]);
                        name[count] = fields[0];
                    count++;
                    }
                reader.Close();
            }


            for (int i = 0; i < user_total; i++)
            {
                PersorScore persorScore = new PersorScore();
                persorScore.Name = name[i];
                persorScore.head_portrait = $"file\\{i + 2}.png";
                persorScore.score = score[i];
                persorScore.money = money_all[i];
                persorScores[i] = persorScore;
            }
            return persorScores;
        }

        /// <summary>
        /// 键盘操作
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                case (Keys.Up):
                    s.turn(gameMap);
                    break;
                case (Keys.Down):
                    timer2.Interval = 50;
                    break;
                case (Keys.Right):
                    s.moveRight(gameMap);
                    break;
                case (Keys.Left):
                    s.moveLeft(gameMap);
                    break;
                case (Keys.Space):

                    if (!pause)
                    {
                        timer2.Stop();
                    }
                    else
                    {
                        timer2.Start();
                    }
                    pause = !pause;
                    break;
                case (Keys.L):
                    if (canSwitch)
                    {
                        if (lockBoolean)
                        {
                            Ram = randomShape();
                            Ram = Lock;
                            Lock = Next;
                            Next = Ram;
                        }
                        else
                        {
                            Lock = Next;
                            Next = randomShape();
                            lockBoolean = true;
                        }
                        subGraphics.Clear(ColorTranslator.FromHtml("#C7D9E3"));
                        lockGraphics.Clear(ColorTranslator.FromHtml("#C7D9E3"));
                        Lock.shapeDrawSub(lockGraphics);
                        Next.shapeDrawSub(subGraphics);
                        canSwitch = false;
                    }
                    break;
            }
        }

        private void panel1_Paint(object sender, PaintEventArgs e)
        {

        }

        private void panel2_Paint(object sender, PaintEventArgs e)
        {

        }

/*        private void button1_Click(object sender, EventArgs e)
        {
            timer2.Stop();
            MessageBox.Show("游戏停止", "游戏结束了~~");
            Environment.Exit(0);
        }*/

        private void listView1_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

/*        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            // 将焦点设置到父容器上
            //this.ActiveControl = this;



            if (comboBox1.Text == "难度二")
            {
                interval = 4 * interval / 5 ;
            }
            else if(comboBox1.Text == "难度三")
            {
                interval = 3 * interval / 5;
            }
            else if (comboBox1.Text == "难度四")
            {
                interval = 2 * interval / 5;
            }
            else if (comboBox1.Text == "难度五")
            {
                interval =  interval / 5;
            }
        }*/

        private void richTextBox1_TextChanged(object sender, EventArgs e)
        {
            
        }

        private void button1_Click_1(object sender, EventArgs e)
        {
            InputForm1 inputForm1 = new InputForm1();

            // 显示输入界面窗体并等待用户输入
            inputForm1.ShowDialog();

            set_difficulty();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            timer2.Stop();

        }

        private void button3_Click(object sender, EventArgs e)
        {
            File.WriteAllText(path, result);

            timer2.Stop();
            MessageBox.Show("游戏结束", "游戏结束了~~");
            Environment.Exit(0);
        }

        private void button4_Click(object sender, EventArgs e)
        {
            timer2.Start();

        }


        private void button6_Click(object sender, EventArgs e)
        {
            InputForm2 inputForm2 = new InputForm2();
            inputForm2.ShowDialog();
            if (isNumeric)
            {
                label8.Text = (money + int.Parse(label8.Text)).ToString("000000");
                
            }
            if(int.Parse(label8.Text) >= money1)
            {
                技能一ToolStripMenuItem.Enabled = true;
            }
            else
            {
                技能一ToolStripMenuItem.Enabled = false;
            }
            if (int.Parse(label8.Text) >= money1)
            {
                技能二ToolStripMenuItem.Enabled = true;
            }
            else
            {
                技能二ToolStripMenuItem.Enabled = false;
            }
            if (int.Parse(label8.Text) >= money1)
            {
                启动提示ToolStripMenuItem.Enabled = true;
            }
            else
            {
                启动提示ToolStripMenuItem.Enabled = false;
            }
            if (int.Parse(label8.Text) >= money1)
            {
                清除一行ToolStripMenuItem.Enabled = true;
            }
            else
            {
                清除一行ToolStripMenuItem.Enabled = false;
            }
        }



        private void listView1_DrawItem(object sender, DrawListViewItemEventArgs e)
        {

        }

        private void listView1_DrawSubItem(object sender, DrawListViewSubItemEventArgs e)
        {
           // e.DrawDefault = true;
        }

        private void listView1_DrawColumnHeader(object sender, DrawListViewColumnHeaderEventArgs e)
        {
            //e.DrawDefault = true;
        }

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
/*            listView1.BackColor = Color.Transparent;
            listView1.ForeColor=Color.Transparent;*/
        }

        private void 技能一ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ifSpecialBlock = true;
            int balance = int.Parse(label8.Text);
            label8.Text = (balance - money1).ToString("000000");
            if (int.Parse(label8.Text) >= money1)
            {
               // button5.Enabled = true;
                技能一ToolStripMenuItem.Enabled = true;
            }
            else
            {
                技能一ToolStripMenuItem.Enabled = false;
            }
        }

        private void 技能二ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            interval_Reduce += 50;
            int balance = int.Parse(label8.Text);
            label8.Text = (balance - money1).ToString("000000");
            if (int.Parse(label8.Text) >= money1)
            {
                // button5.Enabled = true;
                技能二ToolStripMenuItem.Enabled = true;
            }
            else
            {
                技能二ToolStripMenuItem.Enabled = false;
            }
        }

        private void 启动提示ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (enableCalculate)
            {
                promptShape = null;
                enableCalculate = false;
                启动提示ToolStripMenuItem.Text = "启用提示";
            }
            else
            {
                enableCalculate = true;
                启动提示ToolStripMenuItem.Text = "禁用提示";
            }
            int balance = int.Parse(label8.Text);
            label8.Text = (balance - money1).ToString("000000");
            if (int.Parse(label8.Text) >= money1)
            {
                // button5.Enabled = true;
                启动提示ToolStripMenuItem.Enabled = true;
            }
            else
            {
                启动提示ToolStripMenuItem.Enabled = false;
            }
        }

        private void 清除一行ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ifCleanALine = true;

            int balance = int.Parse(label8.Text);
            label8.Text = (balance - money1).ToString("000000");
            if (int.Parse(label8.Text) >= money1)
            {
                // button5.Enabled = true;
                清除一行ToolStripMenuItem.Enabled = true;
            }
            else
            {
                清除一行ToolStripMenuItem.Enabled = false;
            }
        }

        private void 一级ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            interval = interval_grade;
            intervalSaver = interval;
        }

        private void 二级ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            interval = 4 * interval_grade / 5;
            intervalSaver = interval;
        }

        private void 三级ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            interval = 3 * interval_grade / 5;
            intervalSaver = interval;
        }

        private void 四级ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            interval = 2 * interval_grade / 5;
            intervalSaver = interval;
        }

        private void 五级ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            interval = interval_grade / 5;
            intervalSaver = interval;
        }
    }
    /// <summary>
    /// 块类，基本方块；四个方块组成一个形状
    /// </summary> 
    class Block
    {
        /// <summary>
        /// 块的字段有位置坐标X，Y，形状枚举，颜色可以用枚举生成
        /// </summary>
        int _x, _y;
        ShapeType _shape;
        Color c;
        /// <summary>
        ///  构造方法
        /// </summary>
        /// <param name="x">位置坐标x</param>
        /// <param name="y">位置坐标y</param>
        /// <param name="s">形状枚举</param>
        public Block(int x, int y, ShapeType s)
        {
            this._x = x;
            this._y = y;
            this._shape = s;
            c = FunctionCollection.getColor(s);
        }

        public Block(Block o)
        {
            this._x = o._x;
            this._y = o._y;
            this._shape = o._shape;
        }
        /// <summary>
        /// 判定块是不是能被接受,不能超地图，不能在地图上叠加
        /// </summary>
        /// <param name="map">游戏地图</param>
        /// <returns>接受情况</returns>
        public Boolean canAccept(int[,] map)
        {
            if (this._x >= map.GetLength(0) || this._x < 0 || this._y >= map.GetLength(1) || map[this._x, this._y] != 0)
            {
                return false;
            }
            return true;
        }
        /// <summary>
        /// 添加块至游戏地图
        /// </summary>
        /// <param name="map">游戏地图</param>
        public void addToMap(int[,] map)
        {
            //因为数组是引用类型，改了外面就改了
            map[this._x, this._y] = (int)this._shape;
        }

        public void removeFromMap(int[,] map)
        {
            map[this._x, this._y] = 0;
        }

        /// <summary>
        /// 窗口绘制块
        /// </summary>
        /// <param name="g">绘图窗口</param>
        public void drawBlock(Graphics g)
        {

            Color lightColor = ControlPaint.Light(this.c, 0.5f);
            Color darkColor = ControlPaint.Dark(this.c, 0.5f);
            LinearGradientBrush brush = new LinearGradientBrush(new Rectangle(this._x * 20, this._y * 20, 20, 20), lightColor, darkColor, LinearGradientMode.ForwardDiagonal);

            // 填充矩形
            g.FillRectangle(brush, new Rectangle(this._x * 20, this._y * 20, 20, 20));

            // 添加边框
            Pen borderPen = new Pen(this.c, 2);
            g.DrawRectangle(borderPen, this._x * 20, this._y * 20, 20, 20);

            // 添加内阴影效果
            Color innerShadowColor = Color.FromArgb(100, Color.Black);
            PathGradientBrush innerShadowBrush = new PathGradientBrush(new Point[] { new Point(this._x * 20, this._y * 20), new Point(this._x * 20 + 20, this._y * 20), new Point(this._x * 20, this._y * 20 + 20) });
            innerShadowBrush.CenterColor = innerShadowColor;
            innerShadowBrush.SurroundColors = new Color[] { Color.Transparent };
            g.FillRectangle(innerShadowBrush, this._x * 20, this._y * 20, 20, 20);

            //g.FillRectangle(new SolidBrush(this.c), new Rectangle(this._x * 20, this._y * 20, 20, 20));
        }
        /// <summary>
        /// 小窗口绘图
        /// </summary>
        /// <param name="g"></param>
        /// <param name="x">偏移距离</param>
        /// <param name="y">偏移距离</param>
        public void drawBlockSub(Graphics g, int x, int y)
        {
            Color lightColor = ControlPaint.Light(this.c, 0.5f);
            Color darkColor = ControlPaint.Dark(this.c, 0.5f);

            LinearGradientBrush brush = new LinearGradientBrush(new Rectangle(this._x * 20 + x, this._y * 20 + y, 20, 20), lightColor, darkColor, LinearGradientMode.ForwardDiagonal);

            // 填充矩形
            g.FillRectangle(brush, new Rectangle(this._x * 20 + x, this._y * 20 + y, 20, 20));

            // 添加边框
            Pen borderPen = new Pen(this.c, 2);
            g.DrawRectangle(borderPen, this._x * 20 + x, this._y * 20 + y, 20, 20);

            // 添加内阴影效果
            Color innerShadowColor = Color.FromArgb(100, Color.Black);
            PathGradientBrush innerShadowBrush = new PathGradientBrush(new Point[] { new Point(this._x * 20 + x, this._y * 20 + y), new Point(this._x * 20 + x + 20, this._y * 20 + y), new Point(this._x * 20 + x, this._y * 20 + y + 20) });
            innerShadowBrush.CenterColor = innerShadowColor;
            innerShadowBrush.SurroundColors = new Color[] { Color.Transparent };
            g.FillRectangle(innerShadowBrush, this._x * 20 + x, this._y * 20 + y, 20, 20);
        }

        public bool contain(int x, int y)
        {
            return _x == x && _y == y;
        }


        /*******************************************设计穿墙块新加的功能************************************************/


        public Block(int x, int y, ShapeType s, int preX, int preY, int preType)
        {
            this._x = x;
            this._y = y;
            this._shape = s;
            c = FunctionCollection.getColor(s);

            tempSaveX = preX;
            tempSaveY = preY;
            tempSaveType = preType;

        }


        public bool specialcanAccept(int[,] map, ref int X, ref int Y, ref int Type)
        {
            //如果有上次移动保存的数据，则把这个数据还原回去


            if (tempSaveX != 0)
            {
                map[tempSaveX, tempSaveY] = tempSaveType;
            }

            //不能超过地图范围
            if (this._x >= map.GetLength(0) || this._x < 0 || this._y >= map.GetLength(1))
            {
                return false;
            }

            if (map[this._x, this._y] != 0)
            {
                X = this._x;
                Y = this._y;
                Type = map[this._x, this._y];
            }



            return true;
        }

        public bool oneBlockCanAdd(int[,] map)
        {
            if (map[this._x, this._y] == 0)
                return true;
            return false;
        }



        int tempSaveX = 0;
        int tempSaveY = 0;
        int tempSaveType = 0;


        /*******************************************设计穿墙块新加的功能************************************************/


    }
    /// <summary>
    /// 形状父类，写一些可以复用的方法
    /// </summary>
    class Shape
    {
        public int[,] _organizeArray;//组织矩阵分为三类O，I与其他，分别是2×2，4×4，3×3
        public ShapeType _shape;
        public Block[] block;
        public int _x = 4, _y = 0;
        public Image backgroundImage { get;set; }
        internal ShapeType shape
        {
            get { return _shape; }
            set { _shape = value; }
        }
        /// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="st">形状类型</param>
        public Shape(ShapeType st)
        {
            this.shape = st;
            //初始化构造矩阵
            switch (st)
            {
                case (ShapeType.O): this._organizeArray = new int[2, 2];
                    break;
                case (ShapeType.I): this._organizeArray = new int[4, 4];
                    break;
                case (ShapeType.OB):
                    this._organizeArray = new int[1, 1];
                    break;
                default: this._organizeArray = new int[3, 3];
                    break;
            }
            //穿墙块类只有1个块
            if (st != ShapeType.OB)
            {
                //生成4个块
                block = new Block[4];
            }
            else
                block = new Block[1];
        }
        /// <summary>
        /// 初始化块位置,可以重新生成
        /// </summary>
        public void initBlock()
        {
            int i = 0;
            for (int j = 0; j < this._organizeArray.GetLength(0); j++)
            {
                for (int k = 0; k < this._organizeArray.GetLength(1); k++)
                {
                    if (this._organizeArray[j, k] != 0)
                    {
                        block[i] = new Block(this._x + j, _y + k, this._shape);
                        i++;
                    }
                }
            }
        }
        /// <summary>
        /// 主窗口绘图
        /// </summary>
        /// <param name="g">窗口面板</param>
        public void shapeDrawMain(Graphics g)
        {
            Bitmap buffer = new Bitmap(500, 800);
            Graphics bufferGraphics = Graphics.FromImage(buffer);
            //bufferGraphics.Clear(ColorTranslator.FromHtml("#CCCCFF"));
            //前面4个不要画出来
            this._y = this._y - 4;
            initBlock();
            this._y = this._y + 4;

            foreach (Block item in block)
            {
                item.drawBlock(g);
            }
            // 将缓冲区的内容绘制到控件上
           // g.DrawImage(buffer, 0, 0);
            g.DrawImageUnscaled(buffer, 0, 0);
            // 将缓冲区一次性绘制到屏幕上


            // 释放资源
           bufferGraphics.Dispose();
           buffer.Dispose();
        }
        /// <summary>
        /// 副窗口绘图,虚方法可以重写
        /// </summary>
        /// <param name="g">窗口面板</param>
        public virtual void shapeDrawSub(Graphics g)
        {

        }
        /// <summary>
        /// 判定下个行动是否可以执行，旋转或移动，为设计穿墙砖块改为可重写的
        /// </summary>
        /// <returns></returns>
        public virtual Boolean canAct(int[,] map)
        {
            Boolean b = true;
            foreach (Block item in block)
            {
                b = b && item.canAccept(map);
            }
            return b;
        }
        /*        /// <summary>
                /// 判定下个行动是否可以执行，旋转或移动
                /// </summary>
                /// <returns></returns>
                public Boolean canAct(int[,] map)
                {
                    Boolean b = true;
                    foreach (Block item in block)
                    {
                        b = b && item.canAccept(map);
                    }
                    return b;
                }*/
 
        #region 行为模块，移动与旋转;
        public Boolean moveDown(int[,] map)
        {
            return this.moveDown(map, true);
        }
        public Boolean moveDown(int[,] map, bool needToAdd)
        {
            //都是一个逻辑：移动一下生成4个块看有没有问题，有问题变回去,重新初始一下块
            //下移，比较特别需要返回一个布尔类型，我们判定它已经被加入地图了，我们需要一个新的块了
            this._y++;
            initBlock();
            if (canAct(map))
            {
                return true;
            }
            else
            {
                this._y--;
                initBlock();
                if (needToAdd)
                {
                    // 落地音效
                    System.Media.SystemSounds.Asterisk.Play();
                    addToMap(map);
                }
                return false;
            }
        }
        public void moveLeft(int[,] map)
        {
            this._x--;
            initBlock();
            if (canAct(map))
            {

            }
            else
            {
                this._x++;
                initBlock();
            }
        }
        public void moveRight(int[,] map)
        {
            this._x++;
            initBlock();
            if (canAct(map))
            {

            }
            else
            {
                this._x--;
                initBlock();
            }
        }
        /// <summary>
        /// 旋转与移动一样，转一下看看能不能接受，不能赶快转回去
        /// </summary>
        /// <param name="map"></param>
        /// 
        public void turn(int[,] map)
        {
            turn(map, false);
        }
        public void turn(int[,] map, bool force)
        {
            turnShape();
            initBlock();
            if (canAct(map))
            {

            }
            else
            {
                if (!force)
                {
                    cancelTurnShape();
                    initBlock();
                }
            }
        }

        #endregion
        /// <summary>
        /// 旋转矩阵就可以，虚方法可以重写
        /// </summary>
        /// <param name="map"></param>
        public virtual void turnShape()
        {

        }
        /// <summary>
        /// 这个是转回去的方法只要操作矩阵就可以了
        /// </summary>
        /// <param name="map"></param>
        public virtual void cancelTurnShape()
        {

        }
        /// <summary>
        /// 把形状添加到地图里面
        /// </summary>
        /// <param name="map"></param>
        public virtual void addToMap(int[,] map)
        {
            foreach (Block item in block)
            {
                item.addToMap(map);
            }
        }
        public void removeFromMap(int[,] map)
        {
            foreach (Block item in block)
            {
                item.removeFromMap(map);
            }
        }

        public bool contain(int x, int y)
        {
            foreach (Block item in block)
            {
                if (item.contain(x, y)) return true;
            }
            return false;
        }
    }
    class shapeO : Shape
    {
        /// <summary>
        /// 调用一下父类的构造函数可以减少代码量
        /// </summary>
        /// 
        public shapeO()
            : base(ShapeType.O)
        {
            //将O里面每个都填上对应的（int）ShapeType
            for (int j = 0; j < this._organizeArray.GetLength(0); j++)
            {
                for (int k = 0; k < this._organizeArray.GetLength(1); k++)
                {
                    this._organizeArray[j, k] = (int)this._shape;
                }
            }
            initBlock();
        }
        /// <summary>
        /// 小窗口绘图
        /// </summary>
        /// <param name="g"></param>
        public override void shapeDrawSub(Graphics g)
        {
            Bitmap buffer = new Bitmap(200, 200);
            Graphics bufferGraphics = Graphics.FromImage(buffer);

/*            int targetX = -12;
            int targetY = -42;
            Rectangle targetRect = new Rectangle(targetX, targetY, this.backgroundImage.Width, this.backgroundImage.Height);
            //bufferGraphics.Clear(Color.Transparent);
            // 绘制背景图像
            bufferGraphics.DrawImage(this.backgroundImage, targetRect);*/

            // bufferGraphics.Clear(ColorTranslator.FromHtml("#CCCCFF"));
            // bufferGraphics.Clear(Color.Transparent);
            //g.Clear(Color.Transparent);
            foreach (Block item in block)
            {

                item.drawBlockSub(bufferGraphics, -50, 25);
            }
            // 将缓冲区的内容绘制到控件上
            g.DrawImage(buffer, 0, 0);
           // g.DrawImageUnscaled(buffer, 0, 0);
            // 将缓冲区一次性绘制到屏幕上
   

            // 释放资源
            bufferGraphics.Dispose();
            buffer.Dispose();
        }
    }
    /// <summary>
    /// I类形状的写法
    /// </summary>
    class shapeI : Shape
    {
        public shapeI()
            : base(ShapeType.I)
        {
            //将I里面每个都填上对应的（int）ShapeType
            this._organizeArray[1, 0] = (int)this._shape;
            this._organizeArray[1, 1] = (int)this._shape;
            this._organizeArray[1, 2] = (int)this._shape;
            this._organizeArray[1, 3] = (int)this._shape;
            initBlock();
        }
        public override void turnShape()
        {
            //I块只有两种变换横跟竖,判断一个不相交的块是不是0就可以确定它的状态了
            if (this._organizeArray[1, 0] == 0)
            {
                //清空一下组织矩阵
                Array.Clear(this._organizeArray, 0, this._organizeArray.Length);
                this._organizeArray[1, 0] = (int)this._shape;
                this._organizeArray[1, 1] = (int)this._shape;
                this._organizeArray[1, 2] = (int)this._shape;
                this._organizeArray[1, 3] = (int)this._shape;
            }
            else
            {
                //清空一下组织矩阵
                Array.Clear(this._organizeArray, 0, this._organizeArray.Length);
                this._organizeArray[0, 1] = (int)this._shape;
                this._organizeArray[1, 1] = (int)this._shape;
                this._organizeArray[2, 1] = (int)this._shape;
                this._organizeArray[3, 1] = (int)this._shape;
            }
        }
        public override void cancelTurnShape()
        {
            //I类很特殊，取消变换就是在调用一下旋转函数；
            turnShape();
        }
        public override void shapeDrawSub(Graphics g)
        {
            Bitmap buffer = new Bitmap(200, 200);
            Graphics bufferGraphics = Graphics.FromImage(buffer);
/*            int targetX = -12;
            int targetY = -42;
            Rectangle targetRect = new Rectangle(targetX, targetY, this.backgroundImage.Width, this.backgroundImage.Height);
            bufferGraphics.DrawImage(this.backgroundImage, targetRect);*/
            //bufferGraphics.Clear(ColorTranslator.FromHtml("#CCCCFF"));
            //  bufferGraphics.Clear(Color.Transparent);
            // g.Clear(Color.Transparent);
            foreach (Block item in block)
            {

                //试出来的比较好看的值
                item.drawBlockSub(bufferGraphics, -60, 10);
            }
            // 将缓冲区的内容绘制到控件上
            g.DrawImage(buffer, 0, 0);
            // g.DrawImageUnscaled(buffer, 0, 0);
            // 将缓冲区一次性绘制到屏幕上


            // 释放资源
            bufferGraphics.Dispose();
            buffer.Dispose();
        }
    }

    //穿墙块类，只有一个块大小，不能旋转，可以穿过其他砖块，落到底部时，如果此时是个空位，则占据这个空间，如果不是空位，则直接消失
    //颜色设置为黑色
    //只有在允许穿墙块出现时才会出现，如果不设置穿墙块出现，穿墙块就不会出现
    //直接用类似O的方式
    class shapeOneBlock : Shape
    {
        /// <summary>
        /// 调用一下父类的构造函数可以减少代码量
        /// </summary>
        public shapeOneBlock()
            : base(ShapeType.OB)
        {
            this._organizeArray[0, 0] = (int)this._shape;
            initBlock();
        }
        //新的初始化方法
        public void initBlock(int x, int y, int type)
        {
            int i = 0;
            for (int j = 0; j < this._organizeArray.GetLength(0); j++)
            {
                for (int k = 0; k < this._organizeArray.GetLength(1); k++)
                {
                    if (this._organizeArray[j, k] != 0)
                    {
                        block[i] = new Block(this._x + j, _y + k, this._shape, x, y, type);
                        i++;
                    }
                }
            }
        }

        //新的添加到Map中的方法
        public override void addToMap(int[,] map)
        {

            foreach (Block item in block)
            {
                if (item.oneBlockCanAdd(map))
                {
                    item.addToMap(map);
                }
            }

        }

        //判断是否Act
        public override Boolean canAct(int[,] map)
        {
            Boolean b = true;

            foreach (Block item in block)
            {
                b = b && item.specialcanAccept(map, ref X, ref Y, ref Type);
            }

            return b;
        }

        /// <summary>
        /// 小窗口绘图
        /// </summary>
        /// <param name="g"></param>
        public override void shapeDrawSub(Graphics g)
        {
            Bitmap buffer = new Bitmap(200, 200);
            Graphics bufferGraphics = Graphics.FromImage(buffer);

/*            int targetX = -12;
            int targetY = -42;
            Rectangle targetRect = new Rectangle(targetX, targetY, this.backgroundImage.Width, this.backgroundImage.Height);
            bufferGraphics.DrawImage(this.backgroundImage, targetRect);*/
            //bufferGraphics.Clear(ColorTranslator.FromHtml("#CCCCFF"));
            //bufferGraphics.Clear(Color.Transparent);
            //g.Clear(Color.Transparent);
            foreach (Block item in block)
            {
                item.drawBlockSub(bufferGraphics, -50, 25);
            }
            // 将缓冲区的内容绘制到控件上
            g.DrawImage(buffer, 0, 0);
            // g.DrawImageUnscaled(buffer, 0, 0);
            // 将缓冲区一次性绘制到屏幕上


            // 释放资源
            bufferGraphics.Dispose();
            buffer.Dispose();
        }

        int X;
        int Y;
        int Type;

    }
    class shapeOther : Shape
    {
        public shapeOther(ShapeType s)
            : base(s)
        {
            ///这里初始化的是3×3矩阵
            switch (s)
            {
                //把对应形状添加到组织矩阵中
                case (ShapeType.J):
                    this._organizeArray[0, 1] = (int)this._shape;
                    this._organizeArray[1, 1] = (int)this._shape;
                    this._organizeArray[2, 1] = (int)this._shape;
                    this._organizeArray[2, 0] = (int)this._shape;
                    break;
                case (ShapeType.L):
                    this._organizeArray[0, 1] = (int)this._shape;
                    this._organizeArray[1, 1] = (int)this._shape;
                    this._organizeArray[2, 1] = (int)this._shape;
                    this._organizeArray[2, 2] = (int)this._shape;
                    break;
                case (ShapeType.S):
                    this._organizeArray[0, 2] = (int)this._shape;
                    this._organizeArray[0, 1] = (int)this._shape;
                    this._organizeArray[1, 0] = (int)this._shape;
                    this._organizeArray[1, 1] = (int)this._shape;
                    break;
                case (ShapeType.T):
                    this._organizeArray[0, 1] = (int)this._shape;
                    this._organizeArray[1, 1] = (int)this._shape;
                    this._organizeArray[2, 1] = (int)this._shape;
                    this._organizeArray[1, 0] = (int)this._shape;
                    break;
                case (ShapeType.Z):
                    this._organizeArray[0, 0] = (int)this._shape;
                    this._organizeArray[0, 1] = (int)this._shape;
                    this._organizeArray[1, 1] = (int)this._shape;
                    this._organizeArray[1, 2] = (int)this._shape;
                    break;
            }
            initBlock();
        }
        public override void cancelTurnShape()
        {
            //暴力一下把对应顺时针旋转的写进去1，1不用写
            //需要一个中间变量保存后数组清空再调用
            int[,] arrayRam = new int[3, 3];
            Array.Copy(this._organizeArray, arrayRam, 9);
            this._organizeArray[0, 0] = arrayRam[2, 0];
            this._organizeArray[0, 1] = arrayRam[1, 0];
            this._organizeArray[0, 2] = arrayRam[0, 0];
            this._organizeArray[1, 2] = arrayRam[0, 1];
            this._organizeArray[2, 2] = arrayRam[0, 2];
            this._organizeArray[2, 1] = arrayRam[1, 2];
            this._organizeArray[2, 0] = arrayRam[2, 2];
            this._organizeArray[1, 0] = arrayRam[2, 1];
        }
        public override void turnShape()
        {
            //再把逆时针旋转的写进去
            int[,] arrayRam = new int[3, 3];
            Array.Copy(this._organizeArray, arrayRam, 9);
            this._organizeArray[2, 0] = arrayRam[0, 0];
            this._organizeArray[1, 0] = arrayRam[0, 1];
            this._organizeArray[0, 0] = arrayRam[0, 2];
            this._organizeArray[0, 1] = arrayRam[1, 2];
            this._organizeArray[0, 2] = arrayRam[2, 2];
            this._organizeArray[1, 2] = arrayRam[2, 1];
            this._organizeArray[2, 2] = arrayRam[2, 0];
            this._organizeArray[2, 1] = arrayRam[1, 0];
        }
        public override void shapeDrawSub(Graphics g)
        {
            Bitmap buffer = new Bitmap(200, 200);
            Graphics bufferGraphics = Graphics.FromImage(buffer);
/*
            int targetX = -12;
            int targetY = -42;
            Rectangle targetRect = new Rectangle(targetX, targetY, this.backgroundImage.Width, this.backgroundImage.Height);
            bufferGraphics.DrawImage(this.backgroundImage, targetRect);*/
            // bufferGraphics.Clear(ColorTranslator.FromHtml("#CCCCFF"));
            // bufferGraphics.Clear(Color.Transparent);
            // g.Clear(Color.Transparent);
            foreach (Block item in block)
            {
                //试出来的比较好看的值

                item.drawBlockSub(bufferGraphics, -63, 10);
            }
            // 将缓冲区的内容绘制到控件上
            g.DrawImage(buffer, 0, 0);
            // g.DrawImageUnscaled(buffer, 0, 0);
            // 将缓冲区一次性绘制到屏幕上


            // 释放资源
            bufferGraphics.Dispose();
            buffer.Dispose();
        }
    }

    /// <summary>
    /// 公共方法集合静态方法放在这里
    /// </summary>
    static class FunctionCollection
    {
        /// <summary>
        /// 获取颜色方法
        /// </summary>
        /// <param name="s">形状枚举</param>
        /// <returns>返回形状颜色</returns>
        /// public static Image BackgroundImage { get; set; }

        public static Image BackgroundImage { get; set; }
        public static Color getColor(ShapeType s)
        {
            switch ((int)s)
            {
                case (1): return ColorTranslator.FromHtml("#ad68fa");
                case (2): return ColorTranslator.FromHtml("#63c92e");
                case (3): return ColorTranslator.FromHtml("#fef978");
                case (4): return ColorTranslator.FromHtml("#1f70e3");
                case (5): return ColorTranslator.FromHtml("#52ddec");
                case (6): return ColorTranslator.FromHtml("#ff8315");
                //8是新加的穿墙砖块
                case (8): return Color.Black;
                case (9): return ColorTranslator.FromHtml("#E0E0E0");
                default: return Color.SkyBlue;
                    /*                case (1): return Color.Blue ;
                                    case (2): return Color.Red ;
                                    case (3): return Color.Pink ;
                                    case (4): return Color.Purple ;
                                    case (5): return Color.Orange ;
                                    case (6): return Color.SeaGreen ;
                                    default: return Color.SkyBlue;*/
            }
        }
        /// <summary>
        /// 把地图绘制出来
        /// </summary>
        /// <param name="map">地图</param>
        /// <param name="g">主面板</param>
        public static void mapDraw1(int[,] map, Graphics g)
        {
            // 创建双缓冲绘图表面
            Bitmap buffer = new Bitmap((int)g.VisibleClipBounds.Width, (int)g.VisibleClipBounds.Height);
            Graphics bufferGraphics = Graphics.FromImage(buffer);


            int targetX = -12;
            int targetY = -42;
            Rectangle targetRect = new Rectangle(targetX, targetY, FunctionCollection.BackgroundImage.Width, FunctionCollection.BackgroundImage.Height);

            // 绘制背景图像
            g.DrawImage(FunctionCollection.BackgroundImage, targetRect);

            for (int j = 0; j < map.GetLength(0); j++)
            {
                for (int k = 0; k < map.GetLength(1); k++)
                {
                    if (map[j, k] != 0)
                    {

                        /*                        int shapeType = map[j, k];
                                                Color color = getColor((ShapeType)shapeType);
                                                Color lightColor = ControlPaint.Light(color, 0.5f);
                                                Color darkColor = ControlPaint.Dark(color, 0.5f);
                                                LinearGradientBrush brush = new LinearGradientBrush(new Rectangle(j * 20, (k - 4) * 20, 20, 20), lightColor, darkColor, LinearGradientMode.ForwardDiagonal);

                                                // 在缓冲区中绘制
                                                bufferGraphics.FillRectangle(brush, new Rectangle(j * 20, (k - 4) * 20, 20, 20));

                                                // 添加阴影效果
                                                Color shadowColor = Color.FromArgb(100, Color.Black);
                                                Pen shadowPen = new Pen(shadowColor, 2);
                                                bufferGraphics.DrawLine(shadowPen, j * 20, (k - 4) * 20 + 20, j * 20 + 20, (k - 4) * 20 + 20);
                                                bufferGraphics.DrawLine(shadowPen, j * 20 + 20, (k - 4) * 20, j * 20 + 20, (k - 4) * 20 + 20);*/

                        int shapeType = map[j, k];
                        Color color = getColor((ShapeType)shapeType);

                        // 计算矩形位置和大小
                        int x = j * 20;
                        int y = (k - 4) * 20;
                        int width = 20;
                        int height = 20;

                        // 创建渐变画刷
                        LinearGradientBrush brush = new LinearGradientBrush(new Rectangle(x, y, width, height), ControlPaint.Light(color), ControlPaint.Dark(color), LinearGradientMode.Vertical);

                        // 绘制填充矩形
                        g.FillRectangle(new SolidBrush(getColor((ShapeType)map[j, k])), new Rectangle(j * 20, (k - 4) * 20, 20, 20));
                        // 添加边框
                        /*                        Pen borderPen = new Pen(color, 2);
                                                g.DrawRectangle(borderPen, x, y, width, height);

                                                // 添加阴影效果
                                                Color shadowColor = Color.FromArgb(100, Color.Black);
                                                Pen shadowPen = new Pen(shadowColor, 2);
                                                g.DrawLine(shadowPen, x + width, y, x + width, y + height);
                                                g.DrawLine(shadowPen, x, y + height, x + width, y + height);*/

                        /*                        int shapeType = map[j, k];
                                                Color color = getColor((ShapeType)shapeType);
                                                Color lightColor = ControlPaint.Light(color, 0.5f);
                                                Color darkColor = ControlPaint.Dark(color, 0.5f);
                                                LinearGradientBrush brush = new LinearGradientBrush(new Rectangle(j * 20, (k - 4) * 20, 20, 20), lightColor, darkColor, LinearGradientMode.ForwardDiagonal);

                                                // 填充矩形
                                                g.FillRectangle(brush, new Rectangle(j * 20, (k - 4) * 20, 20, 20));

                                                // 添加阴影效果
                                                Color shadowColor = Color.FromArgb(100, Color.Black);
                                                Pen shadowPen = new Pen(shadowColor, 2);
                                                g.DrawLine(shadowPen, j * 20, (k - 4) * 20 + 20, j * 20 + 20, (k - 4) * 20 + 20);
                                                g.DrawLine(shadowPen, j * 20 + 20, (k - 4) * 20, j * 20 + 20, (k - 4) * 20 + 20);*/

                        //  g.FillRectangle(new SolidBrush(getColor((ShapeType)map[j, k])), new Rectangle(j * 20, (k - 4) * 20, 20, 20));
                    }
                }
            }
            // 将绘制结果显示到屏幕上
            g.DrawImage(buffer, 0, 0);
        }

        public static void mapDraw(int[,] map, Graphics g,Shape p ,Shape s )
        {
            // 创建双缓冲区的位图
            Bitmap buffer = new Bitmap(500, 800);
            Graphics bufferGraphics = Graphics.FromImage(buffer);
            //bufferGraphics.Clear(Color.LightSkyBlue); // 使用背景色填充缓冲区
            // bufferGraphics.Clear(ColorTranslator.FromHtml("#659ABC")); // 使用背景色填充缓冲区
            //bufferGraphics.Clear(ColorTranslator.FromHtml("#CCCCFF")); // 使用背景色填充缓冲区
                                                                       //bufferGraphics.Clear(Color.Transparent);
                                                                       //g.Clear(Color.Transparent);
                                                                       // 在缓冲区中绘制图形


            int targetX = -12;
            int targetY = -42;
            Rectangle targetRect = new Rectangle(targetX, targetY, FunctionCollection.BackgroundImage.Width, FunctionCollection.BackgroundImage.Height);
            //bufferGraphics.Clear(Color.Transparent);
            // 绘制背景图像
            bufferGraphics.DrawImage(FunctionCollection.BackgroundImage, targetRect);

            for (int j = 0; j < map.GetLength(0); j++)
            {
                for (int k = 0; k < map.GetLength(1); k++)
                {
                    if (map[j, k] != 0)
                    {
                        int shapeType = map[j, k];
                        Color color = getColor((ShapeType)shapeType);
                        // Color color1 = ControlPaint.Light(color, 0.5f);
                        Color lightColor = ControlPaint.Light(color, 0.5f);
                        Color darkColor = ControlPaint.Dark(color, 0.5f);
                        // 计算矩形位置和大小
                        int x = j * 20;
                        int y = (k - 4) * 20;
                        int width = 20;
                        int height = 20;

                        // 创建渐变画刷
                        LinearGradientBrush brush = new LinearGradientBrush(new Rectangle(x, y, width, height), lightColor, darkColor, LinearGradientMode.ForwardDiagonal);

                        // 在缓冲区中绘制填充矩形
                        bufferGraphics.FillRectangle(brush, new Rectangle(j * 20, (k - 4) * 20, 20, 20));


                        // 添加边框
                        Pen borderPen = new Pen(color, 2);
                        bufferGraphics.DrawRectangle(borderPen, x, y, width, height);

                        // 添加内阴影效果
                        Color innerShadowColor = Color.FromArgb(100, Color.Black);
                        PathGradientBrush innerShadowBrush = new PathGradientBrush(new Point[] { new Point(x, y), new Point(x + width, y), new Point(x, y + height) });
                        innerShadowBrush.CenterColor = innerShadowColor;
                        innerShadowBrush.SurroundColors = new Color[] { Color.Transparent };
                        bufferGraphics.FillRectangle(innerShadowBrush, x, y, width, height);
                        /*                        // 添加阴影效果
                                                Color shadowColor = Color.FromArgb(100, Color.Black);
                                                Pen shadowPen = new Pen(shadowColor, 2);
                                                bufferGraphics.DrawLine(shadowPen, x + width, y, x + width, y + height);
                                                bufferGraphics.DrawLine(shadowPen, x, y + height, x + width, y + height);*/
                    }
                }
            }

            s._y = s._y - 4;
            int i_1 = 0;
            for(int j = 0; j < s._organizeArray.GetLength(0);j++)
            {
                for(int k = 0; k < s._organizeArray.GetLength(1); k++)
                {
                    if (s._organizeArray[j, k] != 0)
                    {
                        s.block[i_1] = new Block(s._x + j, s._y + k,s._shape);
                        i_1++;
                    }
                }
            }
            s._y = s._y + 4;
            foreach (Block item in s.block)
            {
                item.drawBlock(bufferGraphics);
            }

            if(p != null)
            {
                p._y = p._y - 4;
                int i_2 = 0;
                for (int j = 0; j < p._organizeArray.GetLength(0); j++)
                {
                    for (int k = 0; k < p._organizeArray.GetLength(1); k++)
                    {
                        if (p._organizeArray[j, k] != 0)
                        {
                            p.block[i_2] = new Block(p._x + j, p._y + k, p._shape);
                            i_2++;
                        }
                    }
                }
                p._y = p._y + 4;
                foreach (Block item in p.block)
                {
                    item.drawBlock(bufferGraphics);
                }
            }

            // 将缓冲区一次性绘制到屏幕上
            g.DrawImageUnscaled(buffer, 0, 0);

            // 释放资源
            bufferGraphics.Dispose();
            buffer.Dispose();
        }


        /// <summary>
        /// 消除并记分
        /// </summary>
        /// <param name="map"></param>
        /// <returns>分数</returns>
        public static int getScore(int[,] map)
        {
            int Score = 0;
            int i = 0;
            for (int j = 0; j < map.GetLength(1); j++)
            {
                for (int k = 0; k < map.GetLength(0); k++)
                {
                    if (map[k, j] != 0)
                    {
                        i++;
                    }
                }
                if (i == map.GetLength(0))
                {
                    Score++;
                    //这里是消除整个满行
                    for (int w = j; w > 1; w--)
                    {
                        for (int l = 0; l < map.GetLength(0); l++)
                        {
                            map[l, w] = map[l, w - 1];
                        }
                    }
                }
                i = 0;
            }
            switch (Score)
            {
                case (1): return 100;
                case (2): return 300;
                case (3): return 500;
                case (4): return 1000;
                default: return 0;
            }
        }
        public static void gameOver(int[,] map, Timer timer, string result, String path) {
            for (int i = 0; i < map.GetLength(0); i++)
            {
                if (map[i, 3] != 0) {
                    /*
                                       using(StreamWriter writer = new StreamWriter(path))
                                        {
                                            for(int j = 0; j < 10; j++)
                                            {
                                                writer.WriteLine($"{persorScores[i].Name},{persorScores[i].score}");
                                            }

                                        }*/

                    File.WriteAllText(path, result);

                    timer.Stop();
                    MessageBox.Show("游戏结束", "游戏结束了~~");
                    Environment.Exit(0);
                }
            }
        }
    }


    public class PersorScore
    {
        // 定义一个属性
        public string Name { get; set; }

        public string head_portrait { get; set; }
        public int money { get; set; }

        // 定义另一个属性
        public int score { get; set; }
    }

    /*    public PersorScore[] GetMyClassArray()
        {
            PersorScore[] myArray = new PersorScore[3];

            // 为数组中的每个元素赋值
            for (int i = 0; i < myArray.Length; i++)
            {
                PersorScore obj = new PersorScore();
                obj.Name = "Person " + (i + 1);

                myArray[i] = obj;
            }

            return myArray;
        }
    */

    /*    public class RoundedPanel1 : Panel
            {
                private const int CornerRadius = 10;

                public RoundedPanel1()
                {
                    this.BorderStyle = BorderStyle.None;
                }

                protected override void OnPaint(PaintEventArgs e)
                {
                    base.OnPaint(e);

                    // 绘制圆角矩形
                    using (var path = new System.Drawing.Drawing2D.GraphicsPath())
                    {
                        path.AddArc(0, 0, CornerRadius, CornerRadius, 180, 90); // 左上角
                        path.AddArc(Width - CornerRadius, 0, CornerRadius, CornerRadius, 270, 90); // 右上角
                        path.AddArc(Width - CornerRadius, Height - CornerRadius, CornerRadius, CornerRadius, 0, 90); // 右下角
                        path.AddArc(0, Height - CornerRadius, CornerRadius, CornerRadius, 90, 90); // 左下角

                        path.CloseFigure();

                        using (var pen = new Pen(Color.Black, 2))
                        {
                            e.Graphics.DrawPath(pen, path);
                        }
                    }
                }
        }*/




    /*    public class RoundedPanel : Panel
            {
                private const int CornerRadius = 20;

                public RoundedPanel()
                {
                    this.DoubleBuffered = true;
                }

                protected override void OnPaint(PaintEventArgs e)
                {
                    base.OnPaint(e);

                    // 创建圆角矩形路径
                    using (var path = new GraphicsPath())
                    {
                        path.AddArc(0, 0, CornerRadius, CornerRadius, 180, 90); // 左上角
                        path.AddArc(Width - CornerRadius, 0, CornerRadius, CornerRadius, 270, 90); // 右上角
                        path.AddArc(Width - CornerRadius, Height - CornerRadius, CornerRadius, CornerRadius, 0, 90); // 右下角
                        path.AddArc(0, Height - CornerRadius, CornerRadius, CornerRadius, 90, 90); // 左下角

                        path.CloseFigure();

                        // 裁剪绘图区域
                        e.Graphics.SetClip(path);

                        // 绘制背景色
                        e.Graphics.FillRectangle(new SolidBrush(this.BackColor), this.ClientRectangle);

                        // 绘制边框
                        using (var pen = new Pen(this.ForeColor, 2))
                        {
                            e.Graphics.DrawPath(pen, path);
                        }
                    }
                }
            }*/
    static class CalculatePos
    {
        public static Shape calculate(int[,] map, Shape shape, Graphics mainGraphics)
        {
            /**
             * 
                - 1. 获取某方块的所有形态可以放置的所有位置 
                - 2. 计算所有位置的value值和priority值 
             * 
             */
            // 枚举旋转
            // 枚举位置
            // 往下试探
            int _x = shape._x;
            int _y = shape._y;
            int maxValue = -1000000;
            int maxX = 0, maxY = 0, maxTurn = 0;
            for (int i = 0; i < 4; i++)
            {
                shape._x = 4;
                shape._y = 0;
                shape.turn(map, true);
                // 枚举位置
                for (int j = -1; j < map.GetLength(0); j++)
                {
                    shape._x = j;
                    shape._y = 0;
                    while (shape.moveDown(map, false))
                    {
                        Console.WriteLine(shape._x + " " + shape._y);
                    }
                    if (!shape.canAct(map))
                    {
                        continue;
                    }
                    int value = pierreDellacherie(map, shape, false);
                    if (value > maxValue)
                    {
                        maxValue = value;
                        maxX = shape._x;
                        maxY = shape._y;
                        maxTurn = i;

                    }
                }
            }
            shape._x = maxX; shape._y = maxY;
            for(int i=0;i<=maxTurn;i++)
            {
                shape.turn(map, true);
            }


            Shape prompt = new Shape(shape._shape);
            prompt._organizeArray = new int[shape._organizeArray.GetLength(0), shape._organizeArray.GetLength(1)];
            Array.Copy(shape._organizeArray,prompt._organizeArray,shape._organizeArray.Length);
            prompt.block = new Block[shape.block.Length];
            for(int i=0; i<shape.block.Length; i++)
            {
                prompt.block[i] = new Block(shape.block[i]);
            }
            prompt._x = shape._x; prompt._y = shape._y;
            prompt._shape = ShapeType.PROMPT;

            shape._x = _x; shape._y = _y;
            for(int i = maxTurn+1; i < 4; i++)
            {
                shape.turn(map,true);
            }
            return prompt;
        }

        private static int pierreDellacherie(int[,] map, Shape shape, bool show)
        {
            int landingHeight = getLandingHeight(map, shape);
            int erodedPieceCellsMetric = getErodedPieceCellsMetric(map, shape);
            shape.addToMap(map);
            int boardRowTransitions = getBoardRowTransitions(map, shape);
            int boardColTransitions = getBoardColTransitions(map, shape);
            int boardBuriedHoles = getBoardBuriedHoles(map, shape);
            int boardWells = getBoardWells(map, shape);
            shape.removeFromMap(map);
            if (show)
            {
                Console.WriteLine("");
            }
            return -landingHeight + erodedPieceCellsMetric - boardRowTransitions - boardColTransitions
                - 4 * boardBuriedHoles - boardWells;
        }

        private static int getLandingHeight(int[,] map, Shape shape)
        {
            return map.GetLength(1) - shape._y;
        }

        private static int getErodedPieceCellsMetric(int[,] map, Shape shape)
        {
            int Score = 0;
            int hit = 0;
            int i = 0;
            shape.addToMap(map);
            for (int j = 0; j < map.GetLength(1); j++)
            {
                for (int k = 0; k < map.GetLength(0); k++)
                {
                    if (map[k, j] != 0)
                    {
                        i++;
                        if (shape.contain(k, j))
                        {
                            hit++;
                        }
                    }
                }
                if (i == map.GetLength(0))
                {
                    Score++;
                }
                i = 0;
            }

            shape.removeFromMap(map);
            return Score * hit;
        }

        private static int getBoardRowTransitions(int[,] map, Shape shape)
        {
            int res = 0;
            for (int j = 0; j < map.GetLength(1); j++)
            {
                for (int k = 1; k < map.GetLength(0); k++)
                {
                    if ((map[k, j] == 0 && 0 != map[k - 1, j]) ||
                        (map[k, j] != 0 && 0 == map[k - 1, j]))
                    {
                        res++;
                    }
                }
            }
            return res;
        }

        private static int getBoardColTransitions(int[,] map, Shape shape)
        {
            int res = 0;

            for (int k = 0; k < map.GetLength(0); k++)
            {
                bool first = false;
                for (int j = 1; j < map.GetLength(1); j++)
                {
                    if (!first)
                    {
                        if (map[k, j] != 0)
                            first = true;
                        continue;
                    }
                    if ((map[k, j] == 0 && 0 != map[k, j - 1]) ||
                        (map[k, j] != 0 && 0 == map[k, j - 1]))
                    {
                        res++;
                    }
                }
            }

            return res;
        }

        private static int getBoardBuriedHoles(int[,] map, Shape shape)
        {
            int res = 0;

            for (int k = 0; k < map.GetLength(0); k++)
            {
                bool first = false;
                for (int j = 0; j < map.GetLength(1); j++)
                {
                    if (map[k, j] != 0)
                    {
                        first = true;
                    }
                    if (first && map[k, j] == 0)
                    {
                        res++;
                    }
                }
            }
            return res;

        }

        private static int getBoardWells(int[,] map, Shape shape)
        {
            int[] sum_n = new int[] { 0, 1, 3, 6, 10, 15, 21, 28, 36, 45, 55 };
            int wells = 0;
            int res = 0;

            for (int k = 0; k < map.GetLength(0); k++)
            {
                wells = 0;
                for (int j = 0; j < map.GetLength(1); j++)
                {
                    if ((k - 1 < 0 || map[k - 1, j] != 0) &&
                        (k + 1 >= map.GetLength(0) || map[k + 1, j] != 0))
                    {
                        wells++;
                    }
                    else
                    {
                        res += sum_n[wells];
                        wells = 0;
                    }
                }
            }


            /*for (int j = 0; j < map.GetLength(1); j++)
            {
                wells = 0;
                for (int k = 1; k < map.GetLength(0); k++)
                {
                    if( (j-1<0 || map[k,j-1] == 0) && 
                        (j+1 >=  map.GetLength(1) || map[k,j+1] == 0)){
                        wells++;
                    }
                    else
                    {
                        res += sum_n[wells];
                        wells = 0;
                    }
                }
            }*/
            return res;
        }

        private static void show(int[,] map, Shape shape, Graphics mainGraphics)
        {
            shape.addToMap(map);
            mainGraphics.Clear(Control.DefaultBackColor);
            //FunctionCollection.mapDraw(map, mainGraphics);
            shape.removeFromMap(map);
        }
    }


    public class DoubleBufferedPanel : Panel
    {
        public DoubleBufferedPanel()
        {
            DoubleBuffered = true;
        }
    }

    public class TransparentListView : ListView
    {
        private const int LVM_SETBKCOLOR = 0x1001;
        private const int LVM_SETBKIMAGE = 0x108B;

        [DllImport("user32.dll")]
        private static extern int SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);

        protected override void OnHandleCreated(EventArgs e)
        {
            base.OnHandleCreated(e);

            // 设置背景色为透明
            SendMessage(this.Handle, LVM_SETBKCOLOR, IntPtr.Zero, IntPtr.Zero);

            // 设置背景图片为空
            SendMessage(this.Handle, LVM_SETBKIMAGE, IntPtr.Zero, IntPtr.Zero);
        }
    }


}